#ifndef CURLING_STONE_INCLUDED
#define CURLING_STONE_INCLUDED

#include <extvec.hpp>
#include "config.hpp"

namespace curling {

using extvec::vector2d;

/**
 * Stone listener. Communicates events involving the stone.
 */
class stone_listener_t
{
};

/**
 * Default stone properties
 */
namespace default_stone {
  const double mass = 19.96;//[kg] max vikt
  const double radius = 0.15;//[m] 
  const double height = 0.1143;//[m] excluding handle
}

/**
 * Stone color. Indicates team owning the stone.
 */
enum stone_color
{
  color_red,
  color_blue
};
  
/**
 * Stone
 */
class stone
{
  friend class rink;
  
public:
  
  /** Construct a new stone belonging to team <color>. */
  stone( stone_color color );
  /** Destructor */
  ~stone();
  
  /** Mass [kg] */
  double mass() const;
  /** Radius [m] */
  double radius() const;
  /** Height [m] */
  double height() const;
  
  /** Color / Team */
  stone_color color() const;
  /** Position on rink. [m] */
  vector2d position() const;
  /** Velocity [m/s] */
  vector2d velocity() const;
  /** Current rotation, 0 is straight ahead. [rad] */
  double rotation() const;
  /** Rotational velocity [rad/s] */
  double rotational_velocity() const;
  
  /** Move stone to new position. */
  void reposition( vector2d new_position, double new_rotation );
  /** Add accelleration. */
  void accellerate( vector2d add_velocity, double add_rotational_velocity );
  /** True if stone is moving or rotating. */
  bool moving() const;
  
  /** Save stone position. */
  void save_position();
  /** Restore saved position. */
  void restore_position();
  
  /** True if stone is still in play. */
  bool in_play() const;
  /** True if stone has been played. */
  bool played() const;
  /** Activates the stone. */
  void put_into_play();
  /** Deactivates the stone. Typically happens when it goes out-of-bounds. */
  void remove_from_play();
  /** True if stone tagged as point. */
  bool tagged_as_point() const;
  /** Tag as point stone. */
  void tag_as_point();
  /** Untag as point stone. */
  void untag_as_point();
  /** Reset stone to starting position with no movement. */
  void reset();
  
  /**
   * Moves the stone according to velocity and rotation. Collisions are handled
   * in rink.
   */
  void simulate( double dt );
  
protected:
  
  vector2d forward() const;
  vector2d backward() const;
  vector2d left() const;
  vector2d right() const;
  
  double friction_coefficient_slide() const;
  double friction_coefficient_curl() const;
  
private:
  
  /** Color (team) */
  stone_color _color;
  /** Position on rink. Origo is where exactly? */
  vector2d _position;
  /** Saved position on rink. */
  vector2d _saved_position;
  /** Velocity [m/s] */
  vector2d _velocity;
  /** Current rotation. */
  double _rotation;
  /** Rotational velocity [rad/s] */
  double _rotational_velocity;//fram med dynamik-boken
  
  /** True if this stone is still in play. */
  bool _in_play;
  /** True if this stone has been played. */
  bool _played;
  /** True if this stone has been tagged as point stone. */
  bool _tagged_as_point;
};

}

#endif